﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

using JackProjectTemplate.Ability.Docking.Dtos.TestDtos;
using JackProjectTemplate.Ability.Docking.Test;
using JackProjectTemplate.Cache.Cachers.Test;
using JackProjectTemplate.Cache.Ctos.Test;
using JackProjectTemplate.Domain.Data.Test;
using JackProjectTemplate.EntityFrameworkCore;
using JackProjectTemplate.Shared.CommonResult;

using Youshow.Ace.Domain.Repository;
using Youshow.Ace.ModelMapping;
using Youshow.Ace.Wu;

namespace JackProjectTemplate.Ability.Test
{
    /// <summary>
    /// 测试服务
    /// </summary>
    public class TestAppService(IRepository<TestEntity> testRepository, IWorkUnitManager workUnitManager, ITestCacher testCacher, ILogger<TestAppService> logger) : JackAbilityServicer, ITestAppService
    {
        /// <summary>
        /// 获取测试数据
        /// </summary>
        /// <param name="id">数据标识</param>
        /// <returns>测试数据</returns>
        [HttpGet("Get/{id}")]
        [AllowAnonymous]
        public async Task<DataResponse<TestDto>> Get([FromRoute] long id)
        {
            var testCto = await testCacher.GetCache(id);
            if (testCto != null)
                return new DataResponse<TestDto>(ModelMapper.MapEx<TestDto>(testCto.ToEntity()));

            var testEntity = await testRepository.GetAsync(id);
            if (testEntity == null) return DataResponse<TestDto>.CreateFailureResult("未找到数据");

            TestDto testDto = ModelMapper.MapEx<TestDto>(testEntity);
            await testCacher.SetCache(new Cache.Ctos.Test.TestCto(testEntity));

            return new DataResponse<TestDto>(testDto);
        }

        /// <summary>
        /// 获取测试数据
        /// </summary>
        /// <param name="id">数据标识</param>
        /// <returns>测试数据</returns>
        [HttpGet("GetByDbContext/{id}")]
        [AllowAnonymous]
        public async Task<DataResponse<TestDto>> GetByDbContext([FromRoute] long id)
        {
            var testCto = await testCacher.GetCache(id);
            if (testCto != null)
                return new DataResponse<TestDto>(ModelMapper.MapEx<TestDto>(testCto.ToEntity()));

            JackProjectTemplateDbContext jackProjectTemplateDbContext = ServiceProvider.GetRequiredService<JackProjectTemplateDbContext>();
            var testEntity = await jackProjectTemplateDbContext.Query<TestEntity>().FirstOrDefaultAsync(x => x.Id == id);
            if (testEntity == null) return DataResponse<TestDto>.CreateFailureResult("未找到数据");

            TestDto testDto = ModelMapper.MapEx<TestDto>(testEntity);
            testCto = new Cache.Ctos.Test.TestCto(testEntity);
            await testCacher.SetCache(testCto);

            logger.LogInformation("查询数据：{testCto}", testCto);

            return new DataResponse<TestDto>(testDto);
        }

        /// <summary>
        /// 创建测试数据
        /// </summary>
        /// <param name="createDto">创建模型</param>
        /// <returns>测试数据</returns>
        [HttpPost("Create")]
        [AllowAnonymous]
        public async Task<DataResponse<TestDto>> Create([FromBody] TestCreateDto createDto)
        {
            TestEntity testEntity = ModelMapper.MapEx<TestEntity>(createDto);
            testEntity.BirthDay = DateTime.Now;

            await testRepository.InsertAsync(testEntity);
            await workUnitManager.CurrentUnit.SaveChangesAsync();

            await testCacher.SetCache(new Cache.Ctos.Test.TestCto(testEntity));

            TestDto testDto = ModelMapper.MapEx<TestDto>(testEntity);
            return new DataResponse<TestDto>(testDto);
        }

        /// <summary>
        /// 测试日志
        /// </summary>
        [HttpGet("TestSerilog")]
        [AllowAnonymous]
        public async Task TestSerilog()
        {
            //HttpContext
            Random random = new();
            var order = new { OrderNo = Guid.NewGuid().ToString("n"), OrderTime = DateTime.Now, BuyNum = 10, TotalPrice = 29.99m, Environment.MachineName, Environment.CurrentManagedThreadId };
            TestEntity testEntity = new(random.Next(1, 1000)) { Name = $"Jack{random.Next(0, 100)}", Age = random.Next(1, 130), BirthDay = DateTime.Now };
            TestCto testCto = new(testEntity);

            logger.LogInformation("订单信息（匿名类型）：{order}\r\n测试数据库模型：{testEntity}\r\n测试缓存模型：{testCto}", order, testEntity, testCto);
            await Task.CompletedTask;
        }

        [HttpGet("TestSerilogError")]
        [AllowAnonymous]
        public async Task TestSerilogError()
        {
            int a = 1;
            int b = 0;
            int c = a / b;
            await Console.Out.WriteLineAsync(Convert.ToString(c));
            logger.LogInformation($"计算值: {c}");

            await Task.CompletedTask;
        }
    }
}
